package utils

import (
	"bytes"
	"crypto/aes"
	"crypto/cipher"
	"crypto/md5"
	"crypto/sha256"
	"encoding/base64"
	"encoding/binary"
	"encoding/hex"
	"os"
	"path"
	"strings"
)

func ToMD5(s string) string {
	md5 := md5.New()
	md5.Write([]byte(s))
	md5Str := hex.EncodeToString(md5.Sum(nil))
	return md5Str
}

func ToUpperMD5(s string) string {
	md5 := md5.New()
	md5.Write([]byte(s))
	md5Str := hex.EncodeToString(md5.Sum(nil))
	return strings.ToUpper(md5Str)
}

func ToBase64Plus(oriStr string) string {
	base64Str := base64.URLEncoding.EncodeToString([]byte(oriStr))
	base64Str = strings.Replace(base64Str, "=", "-", -1)
	return strings.Replace(base64Str, "/", "_", -1)
}

func PathExists(path string) bool {
	_, err := os.Stat(path)
	if err == nil {
		return true
	}
	if os.IsNotExist(err) {
		return false
	}
	return false
}

func GetCurrPath(subPath string) string {
	str, _ := os.Getwd()
	return path.Join(str, subPath)
}

func IntToBytes(n int) []byte {
	x := int32(n)
	bytesBuffer := bytes.NewBuffer([]byte{})
	binary.Write(bytesBuffer, binary.BigEndian, x)
	return bytesBuffer.Bytes()
}

// GenerateKey 创建一个32字节的密钥，使用SHA-256哈希生成。
func GenerateKey(passphrase string) []byte {
	hash := sha256.Sum256([]byte(passphrase))
	return hash[:]
}

// EncryptAESWithCBC AES加密函数，使用AES/CBC/PKCS5Padding
func EncryptAESWithCBC(plaintext []byte, appKey string) (string, error) {
	// 获取appKey的前16位作为AES密钥
	key := []byte(appKey[:16])

	// 创建AES块加密器
	block, err := aes.NewCipher(key)
	if err != nil {
		return "", err
	}

	// 使用PKCS7填充
	padding := aes.BlockSize - len(plaintext)%aes.BlockSize
	padtext := make([]byte, len(plaintext)+padding)
	copy(padtext, plaintext)
	copy(padtext[len(plaintext):], bytes.Repeat([]byte{byte(padding)}, padding))

	// 使用16个字节的0作为IV
	iv := make([]byte, aes.BlockSize) // 16字节全0的IV

	// 使用CBC模式加密
	ciphertext := make([]byte, len(padtext))
	mode := cipher.NewCBCEncrypter(block, iv)
	mode.CryptBlocks(ciphertext, padtext)

	// 将密文进行Base64编码
	return base64.StdEncoding.EncodeToString(ciphertext), nil
}

// DecryptAESWithECB 使用AES-256加密算法和ECB模式解密密文
func DecryptAESWithECB(ciphertext string, key []byte) (string, error) {
	block, err := aes.NewCipher(key)
	if err != nil {
		return "", err
	}

	decodedCiphertext, err := hex.DecodeString(ciphertext)
	if err != nil {
		return "", err
	}

	plaintext := make([]byte, len(decodedCiphertext))

	for bs, be := 0, block.BlockSize(); bs < len(decodedCiphertext); bs, be = bs+block.BlockSize(), be+block.BlockSize() {
		block.Decrypt(plaintext[bs:be], decodedCiphertext[bs:be])
	}

	// 去除填充部分
	plaintext = bytes.TrimRight(plaintext, "\x00")

	return string(plaintext), nil
}
